﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Innova.Microfinanzas.BusinessEntities;

namespace MyCommerce.Business.Stores
{
    public class ProductStockManager
    {
        private MyCommerceEntities vContext;

        public ProductStockManager()
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = false;
            }
        }

        public ProductStockManager(bool lazyLoad)
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = lazyLoad;
            }
        }

        public List<ProductStock> GetProductStock()
        {
            List<ProductStock> colStock = new List<ProductStock>();

            var result = from st in vContext.ProductStock
                         .Include("Product")
                         .Include("Supplier")
                         .Include("Store")
                         .Include("ProductPrice")
                         select st;
            if (result != null)
                colStock = new List<ProductStock>(result.AsEnumerable<ProductStock>());

            return colStock;
        }

        //public List<ProductStockMassive> GetProductStockMassive()
        //{
        //    List<ProductStockMassive> colStock = new List<ProductStockMassive>();

        //    var result = vContext.ProductStock.GroupBy(x => new { x.Product, x.ProductPrice, x.Supplier, x.Store, x.WithGuarantee })
        //                        .Select(group => new { ProductStock = group.Key, Count = group.Count() });
            
        //    foreach (var item in result)
        //    {
        //        ProductStockMassive objProductStockMassive = new ProductStockMassive();
        //        objProductStockMassive.ObjProduct = item.ProductStock.Product;
        //        objProductStockMassive.ObjPrice = item.ProductStock.ProductPrice;
        //        objProductStockMassive.ObjStore = item.ProductStock.Store;
        //        objProductStockMassive.ObjSupplier = item.ProductStock.Supplier;
        //        objProductStockMassive.WithGuaranty = item.ProductStock.WithGuarantee;
        //        objProductStockMassive.Quantity = item.Count;

        //        colStock.Add(objProductStockMassive);
        //    }            
        //    return colStock;
        //}

        public ProductStock GetProductStockByID(long IdProductStock)
        {
            ProductStock objStock = new ProductStock();
            var result = (from st in vContext.ProductStock
                          where st.IdProductStock == IdProductStock
                          select st).First();
            objStock = (ProductStock)result;
            return objStock;

        }

        public List<ProductStock> GetProductStockByIdStore(long IdStore)
        {
            List<ProductStock> colStock = new List<ProductStock>();
            var result = from st in vContext.ProductStock
                          where st.IdStore == IdStore
                          select st;
            if (result != null)
                colStock = new List<ProductStock>(result.AsEnumerable<ProductStock>());

            return colStock;
        }

        public List<ProductStock> GetProductStockByIdProduct(long IdProduct)
        {
            List<ProductStock> colStock = new List<ProductStock>();
            var result = from st in vContext.ProductStock
                          where st.IdProduct == IdProduct
                          select st;
            if (result != null)
                colStock = new List<ProductStock>(result.AsEnumerable<ProductStock>());

            return colStock;
        }

        public int GetQuantityProductInStock(long IdProduct)
        {
            ProductStock objStock = new ProductStock();
            var result = (from st in vContext.ProductStock
                          where st.IdProduct == IdProduct
                          select st).FirstOrDefault();
            if (result != null)
            {
                objStock = (ProductStock)result;
                return objStock.Quantity;
            }

            return 0;
        }

        //public void SaveCollectionProductStock(ProductStock objProductStock, int count)
        //{
        //    using (vContext)
        //    {
        //        for (int i = 0; i < count; i++)
        //        {
        //            var entity = new ProductStock
        //            {
        //                IdProduct = objProductStock.IdProduct,
        //                IdSupplier = objProductStock.IdSupplier,
        //                IdStore = objProductStock.IdStore,
        //                SerialNumber = objProductStock.SerialNumber,
        //                IdProductPrice = objProductStock.IdProductPrice
        //            };
        //            vContext.ProductStock.AddObject(entity);
        //        }
        //        //vContext.SaveChanges();
        //    }
        //}

        public void SaveProductStockFromDelivery(List<DeliveryStockDetail> colDeliveryStockDetail)
        {
            ProductPriceManager ProductPriceMgr = new ProductPriceManager();

            using (vContext)
            {
                foreach (DeliveryStockDetail item in colDeliveryStockDetail)
                {
                    ProductPrice objProductPrice = ProductPriceMgr.GetProductPriceByProductAndSupplier(item.IdProduct, item.IdSuplier);
                    if (objProductPrice == null)
                    {
                        throw new Exception("El producto enviado no tiene definido un precio.");
                    }
                    var entity = new ProductStock
                    {
                        IdProduct = item.IdProduct,
                        IdSupplier = item.IdSuplier,
                        IdStore = item.IdStore,
                        SerialNumber = string.Empty,
                        IdProductPrice = objProductPrice.IdProductPrice,
                        Quantity = item.Quantity
                    };
                    SaveProductStock(entity);
                }
                vContext.SaveChanges();
            }
        }

        public void SaveProductStock(ProductStock objProductStock)
        {
            var validateResult = (from cl in vContext.ProductStock
                                  where (cl.IdProduct == objProductStock.IdProduct && cl.IdStore == objProductStock.IdStore)
                                  select cl).FirstOrDefault();
            if (validateResult != null)
            {
                SumQuantity(validateResult.IdProductStock, objProductStock.Quantity);
                return;
            }

            vContext.AddToProductStock(objProductStock);
            vContext.SaveChanges();
        }

        public void UpdateQuantityProductStock(long IdProduct, int QuantityToRest)
        {
            var vResult = (from st in vContext.ProductStock
                           where st.IdProduct == IdProduct
                           select st).First();

            vResult.Quantity = vResult.Quantity - QuantityToRest;
            vContext.SaveChanges();
        }

        public void UpdateProductStock(ProductStock objProductStock)
        {
            var vResult = (from st in vContext.ProductStock
                           where st.IdProductStock == objProductStock.IdProductStock
                           select st).First();

            vResult.IdProduct = objProductStock.IdProduct;
            vResult.IdSupplier = objProductStock.IdSupplier;
            vResult.IdStore = objProductStock.IdStore;
            vResult.SerialNumber = objProductStock.SerialNumber;
            vResult.IdProductPrice = objProductStock.IdProductPrice;
            vResult.Quantity = objProductStock.Quantity;

            vContext.SaveChanges();
        }

        public void DeleteProductStock(long IdProductStock)
        {
            var vResult = (from st in vContext.ProductStock
                           where st.IdProductStock == IdProductStock
                           select st).First();
            vContext.DeleteObject(vResult);
            vContext.SaveChanges();
        }

        /// <summary>
        /// transferencia entre almacenes
        /// </summary>
        /// <param name="objStockTransfer"></param>
        public void TransferStock(StockTransfer objStockTransfer)
        {
            if (objStockTransfer.IdStoreOrigen == objStockTransfer.IdStoreDestiny)
            {
                throw new Exception("El almacen origen y destino no pueden ser el mismo.");
            }

            var validateOrigen = (from cl in vContext.ProductStock
                                  where (cl.IdProduct == objStockTransfer.IdProduct && cl.IdStore == objStockTransfer.IdStoreOrigen)
                                  select cl).FirstOrDefault();
            if (objStockTransfer.StockQuantity > validateOrigen.Quantity)
            {
                throw new Exception("La cantidad de productos a enviar es mayor a la disponible del almacen origen.");
            }

            var validateResult = (from cl in vContext.ProductStock
                                  where (cl.IdProduct == objStockTransfer.IdProduct && cl.IdStore == objStockTransfer.IdStoreDestiny)
                                  select cl).FirstOrDefault();
            if (validateResult != null)
            {
                SumQuantity(validateResult.IdProductStock, objStockTransfer.StockQuantity);
                RestQuantity(objStockTransfer.IdProduct, objStockTransfer.IdStoreOrigen, objStockTransfer.StockQuantity);
                return;
            }
            
            ProductStock objProductStock = validateResult;            
            objProductStock.IdProduct = objStockTransfer.IdProduct;
            ProductPriceManager vProductPriceManager = new ProductPriceManager();
            ProductPrice objProductPrice = vProductPriceManager.GetProductPriceByProduct(objStockTransfer.IdProduct);
            if (objProductPrice != null)
            {
                objProductStock.IdProductPrice = objProductPrice.IdProductPrice;
                objProductStock.IdSupplier = objProductPrice.IdSupplier;
            }
            else
                throw new Exception("El producto enviado no tiene definido un precio en el almacen destino.");
            objProductStock.IdStore = objStockTransfer.IdStoreDestiny;
            objProductStock.Quantity = objStockTransfer.StockQuantity;
            objProductStock.SerialNumber = string.Empty;

            vContext.AddToProductStock(objProductStock);
            vContext.SaveChanges();

            RestQuantity(objStockTransfer.IdProduct, objStockTransfer.IdStoreOrigen, objStockTransfer.StockQuantity);
        }

        /// <summary>
        /// suma la cantidad de un producto existente en stock.
        /// </summary>
        /// <param name="IdProductStock"></param>
        /// <param name="Quantity"></param>
        public void SumQuantity(long IdProductStock, int Quantity)
        {
            var vResult = (from st in vContext.ProductStock
                           where st.IdProductStock == IdProductStock
                           select st).First();
            
            vResult.Quantity = vResult.Quantity + Quantity;
            vContext.SaveChanges();
        }

        public void RestQuantity(long IdProduct, long IdStore, int Quantity)
        {
            var vResult = (from st in vContext.ProductStock
                           where st.IdProduct == IdProduct && st.IdStore == IdStore
                           select st).First();

            vResult.Quantity = vResult.Quantity - Quantity;
            vContext.SaveChanges();
        }

    }
}
